package org.cuijq.thinking.in.spring.dependency.lookup;

import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.HierarchicalBeanFactory;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;

/**
 * @Description 层次性依赖查找
 * @Date 2021/4/30 9:58
 * @Created by CuiJQ
 */
public class HierarchicakDependencyLookupDemo {

  public static void main(String[] args) {
    AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext();
    ac.register(HierarchicakDependencyLookupDemo.class);
    ac.refresh();

    //1.获取HierarchicalBeanFactory
    ConfigurableListableBeanFactory beanFactory = ac.getBeanFactory();
    System.out.println("当前beanFactory 的partent BeanFactory:" + beanFactory.getParentBeanFactory());
    //2.设置parent beanFactory
    HierarchicalBeanFactory parentBeanFactory = createParentBeanFactory();
    beanFactory.setParentBeanFactory(parentBeanFactory);
    System.out.println("当前beanFactory 的partent BeanFactory:" + beanFactory.getParentBeanFactory());

    displayContainLocalBean(beanFactory, "user");
    displayContainLocalBean(parentBeanFactory, "user");

    displayContainBean(beanFactory,"user");
    displayContainBean(parentBeanFactory,"user");
    ac.close();
  }

  private static void displayContainBean(HierarchicalBeanFactory beanFactory, String beanName) {
    System.out.printf("当前beanFactory[%s]是否包含 bean[name:%s]:%s\n", beanFactory, beanName,
        beanFactory.containsLocalBean(beanName));
  }

  private static boolean containBean(HierarchicalBeanFactory beanFactory, String beanName) {
    BeanFactory parentBeanFactory = beanFactory.getParentBeanFactory();
    if (parentBeanFactory instanceof HierarchicalBeanFactory) {
      HierarchicalBeanFactory parentHierarchicalBeanFactory = (HierarchicalBeanFactory) parentBeanFactory;
      if (containBean(parentHierarchicalBeanFactory, beanName)) {
        return true;
      }
    }
    return beanFactory.containsLocalBean(beanName);
  }

  private static void displayContainLocalBean(HierarchicalBeanFactory beanFactory,
      String beanName) {
    System.out.printf("当前beanFactory[%s]是否包含 Localbean[name:%s]:%s\n", beanFactory, beanName,
        beanFactory.containsLocalBean(beanName));
  }

  private static ConfigurableListableBeanFactory createParentBeanFactory() {
    DefaultListableBeanFactory defaultListableBeanFactory = new DefaultListableBeanFactory();
    //加载配置
    XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(defaultListableBeanFactory);
    String localtion = "classpath:/META-INF/dependency-lookuo-context.xml";
    reader.loadBeanDefinitions(localtion);
    return defaultListableBeanFactory;
  }

}
